package com.guoj.rabbitmq.task;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.guoj.rabbitmq.entity.BrokerMessageLog;
import com.guoj.rabbitmq.entity.TOrder;
import com.guoj.rabbitmq.sender.RabbitOrderSender;
import com.guoj.rabbitmq.service.IBrokerMessageLogService;

import com.guoj.rabbitmq.utils.Constant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * @author guoj
 * @date 2019/5/30
 * @description 消息重试、最大努力尝试策略（定时任务）
 */
@Component
@Slf4j
public class RetryMessageTask {

    @Autowired
    private RabbitOrderSender orderSender;

    @Autowired
    private IBrokerMessageLogService brokerMessageLogService;

    @Value("${system-constant.max-try-count}")
    private Integer maxTryCount;

    @Scheduled(initialDelay = 3000, fixedDelay = 10000)
    public void reSend() {

        log.debug("----------------------------定时任务开始----------------------------");

        // 查询消息状态为0(发送中) 且已经超时的消息集合
		log.info("################### query4StatusAndTimeoutMessage");
        List<BrokerMessageLog> brokerMessageLogs = brokerMessageLogService.query4StatusAndTimeoutMessage();
        log.info("################### brokerMessageLogs-size: {}", brokerMessageLogs.size());
        log.info(Arrays.toString(brokerMessageLogs.toArray()));
        brokerMessageLogs.forEach(messageLog -> {
            if (messageLog.getTryCount() >= maxTryCount) {
                // 如果失败次数达到3次, 取消重试, 发送警报
				brokerMessageLogService.changeBrokerMessageLogStatus(messageLog.getMessageId(), Constant.ORDER_SEND_FAILURE);
                log.error("messageId={}, 失败次数已达到[{}], 不再进行重试. 请排查", messageLog.getMessageId(), messageLog.getTryCount());
            } else {
                // 修改重试次数
				brokerMessageLogService.update4ReSend(messageLog, LocalDateTime.now());

                // 重试
                TOrder order = JSONObject.parseObject(messageLog.getMessage(), new TypeReference<TOrder>() {});
                orderSender.sendOrder(order);
                log.debug("messageId={}, 进行第{}次重试", messageLog.getMessageId(), messageLog.getTryCount());
            }
        });


    }
}
